/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lvoddownloader;

import Lvod.Config.ConfigLoader;
import Lvod.DownLoader;
import Lvod.IDownloadProgress;
import Lvod.PlayList.HistoryItem;
import Lvod.PlayList.PlayListLoader;
import Lvod.PlayList.VodUrlFilters;
import LvodServer.CharTools;
import LvodServer.JReportQvodUrl;
import LvodServer.SingleHTTPServer;
import java.awt.Dimension;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;

/**
 *
 * @author wcss
 */
public class LDownLoadList extends javax.swing.JPanel implements LDownloadListActionInterface, IDownloadProgress, Runnable, JReportQvodUrl {

    public static LDownLoadList data = null;
    public LinkedHashMap<String, LDownLoadItem> downloadItemMap = new LinkedHashMap<String, LDownLoadItem>();
    public LDownloadListActionInterface downloadActionEvent = null;
    public LDownLoadItem selectedDownLoadItem = null;
    private HashMap<String, SpeedEntry> downloadProgresses = new HashMap<String, SpeedEntry>();
    public LDownLoadItem currentPlay = null;
    public LDownLoadItem lastPlayItem = null;

    /**
     * Creates new form LDownLoadList
     */
    public LDownLoadList() {
        initComponents();
        LDownLoadList.data = this;
    }

    public LDownLoadItem addDownloadItem(String qvodUrl, String saveName, String showName, String showSize) throws Exception {
        LDownLoadItem ldi = new LDownLoadItem();
        DownLoader down = new DownLoader();
        if (down.checkQvodUrl(qvodUrl)) {
            if (downloadItemMap.containsKey(qvodUrl)) {
                throw new Exception("qvodurl in list!");
            } else {
                down.initDownloader(qvodUrl, this);
                ldi.downloaderObj = down;
                ldi.downloadUrl = qvodUrl;
                ldi.bufferUrl = down.movieFile;
                ldi.localUrl = ConfigLoader.config.downloadDir + "/" + saveName;
                ldi.currentState = LDownLoadItem.stopDownload;
                ldi.downloadProgress = 0;
                ldi.actionsListener = this;
                ldi.setMovieName(showName);
                ldi.setMovieInfo(showSize);
                ldi.setDownloadProgress(0);
                ldi.setToolTipText(showName + "," + showSize);
                ldi.addMouseListener(new java.awt.event.MouseAdapter() {

                    public void mouseClicked(java.awt.event.MouseEvent evt) {
                        downloadItemMouseClicked((LDownLoadItem) evt.getSource());
                    }
                });
                double currentSize = down.getCurrentLength();
                System.out.println("名称：" + showName + ",大小：" + currentSize);
                int percent = (int) ((currentSize / down.movieFileLength) * 100);
                ldi.setDownloadProgress(percent);
                ldi.setPlayButton(false);
                ldi.setDownLoadButton(false);
                if (currentSize > 4) {
                    if (currentSize >= down.movieFileLength) {
                        ldi.setPlayButton(true);
                        ldi.setDownloadProgress(100);
                        ldi.setMovieInfo("已完成");
                    } else {
                        ldi.setDownLoadButton(true);
                        ldi.setMovieInfo("未完成");
                        if ((currentSize / down.movieFileLength) * 100 >= 98) {
                            ldi.setPlayButton(true);
                        }
                    }
                } else {
                    String destfile = ConfigLoader.config.downloadDir + "/" + showName;
                    if (new File(destfile).exists()) {
                        ldi.setPlayButton(true);
                        ldi.setDownloadProgress(100);
                        ldi.setMovieInfo("已完成");
                    } else {
                        ldi.setDownLoadButton(true);
                        ldi.setMovieInfo("未下载");
                    }
                }
                this.downloadItemMap.put(qvodUrl, ldi);
                return ldi;
            }

        } else {
            throw new Exception("qvodurl add error!");
        }
    }

    public void uploadDownloadList() {
        this.plItemList.removeAll();
        ArrayList showlists = new ArrayList();
        Object[] downitems = downloadItemMap.values().toArray();
        if (downitems.length > 0) {
            for (int k = downitems.length - 1; k >= 0; k--) {
                showlists.add(downitems[k]);
            }
        }
        this.plItemList.setSize(230, downitems.length * 70 + downitems.length * 10);
        this.plItemList.setPreferredSize(new Dimension(230, downitems.length * 70 + downitems.length * 10));
        this.jScrollPane1.revalidate();
        int index = 0;
        int sindex = 1;
        for (Object obj : showlists) {
            LDownLoadItem ldi = (LDownLoadItem) obj;
            ldi.setnoSelectImageIndex(sindex + "");
            if (sindex == 1) {
                sindex = 2;
            } else {
                sindex = 1;
            }
            ldi.setBounds(5, (index * 70) + (index * 10), 230, 70);
            this.plItemList.add(ldi);
            ldi.setBounds(5, (index * 70) + (index * 10), 230, 70);
            ldi.repaint();
            index++;
        }
        removeAllSelect();
    }

    public void removeAllSelect() {
        Object[] downitems = downloadItemMap.values().toArray();
        for (Object obj : downitems) {
            LDownLoadItem ldi = (LDownLoadItem) obj;
            ldi.selectLeave();
            ldi.checkLayouts();
        }
    }

    public void processActions(LDownLoadItem ldi, String action, String args) {
        if (downloadActionEvent != null) {
            downloadActionEvent.processAction(ldi, action, args);
        }
    }

    public void checkTaskFinish() {
        if (this.selectedDownLoadItem != null) {
            String destfile = ConfigLoader.config.downloadDir + "/" + this.selectedDownLoadItem.movieShowName;
            if (new File(destfile).exists()) {
                this.selectedDownLoadItem.setMovieInfo("已完成");
                this.selectedDownLoadItem.setDownloadProgress(100);
                this.processActions(this.selectedDownLoadItem, ActionLists.writeDownloadInfo, "已完成");

                if (this.currentPlay != null && this.currentPlay.downloadUrl.equals(this.selectedDownLoadItem.downloadUrl)) {
                    //正在播放时不处理
                } else {
                    this.selectedDownLoadItem.setPlayButton(true);
                }
                this.selectedDownLoadItem.setDownLoadButton(false);

            } else {
                this.selectedDownLoadItem.setDownLoadButton(true);
                if (this.currentPlay != null && this.currentPlay.downloadUrl.equals(this.selectedDownLoadItem.downloadUrl)) {
                    //正在播放时不处理
                } else {
                    this.selectedDownLoadItem.setPlayButton(false);
                }
                try {
                    if (((int) ((this.selectedDownLoadItem.downloaderObj.getCurrentLength() / this.selectedDownLoadItem.downloaderObj.movieFileLength) * 100)) >= 98) {
                        if (this.currentPlay != null && this.currentPlay.downloadUrl.equals(this.selectedDownLoadItem.downloadUrl)) {
                            //正在播放时不处理
                        } else {
                            this.selectedDownLoadItem.setPlayButton(true);
                        }
                    }
                } catch (Exception ex) {
                    Logger.getLogger(LDownLoadList.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    private void downloadItemMouseClicked(LDownLoadItem sender) {
        selectedDownLoadItem = sender;
        removeAllSelect();
        sender.selectEnter();
        sender.checkLayouts();
        showTaskProgress(sender.downloadUrl);
        checkTaskFinish();
    }

    public void removeDownloadItem(String qvodUrl) {
        if (this.downloadItemMap.containsKey(qvodUrl)) {
            this.downloadItemMap.remove(qvodUrl);
        }
    }

    /**
     * 检查同时下载是否为3
     */
    private Boolean checkDownloaderMaxCount() {
        Boolean result = false;
        int runningcount = 0;
        Object[] values = this.downloadItemMap.values().toArray();
        for (Object obj : values) {
            LDownLoadItem ldi = (LDownLoadItem) obj;
            if (ldi.downloaderObj.isRunning()) {
                runningcount++;
            }
        }
        if (runningcount < 3) {
            result = true;
        } else {
            result = false;
        }
        return result;
    }

    /**
     * 检查同时下载是否为3
     */
    private int getDownloaderMaxCount() {
        int runningcount = 0;
        Object[] values = this.downloadItemMap.values().toArray();
        for (Object obj : values) {
            LDownLoadItem ldi = (LDownLoadItem) obj;
            if (ldi.downloaderObj.isRunning()) {
                runningcount++;
            }
        }

        return runningcount;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        plItemList = new LPlayerUILib.JImagePanel("/UIImages/playerbgs/downloadlist_bg.JPG");

        setBorder(null);
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });
        setLayout(null);

        jScrollPane1.setBorder(null);
        jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        jScrollPane1.setDoubleBuffered(true);
        jScrollPane1.setMaximumSize(new java.awt.Dimension(255, 32767));

        plItemList.setBorder(null);
        plItemList.setPreferredSize(new java.awt.Dimension(230, 465));
        plItemList.setLayout(null);
        jScrollPane1.setViewportView(plItemList);

        add(jScrollPane1);
        jScrollPane1.setBounds(0, 0, 240, 467);
    }// </editor-fold>//GEN-END:initComponents

    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
        // TODO add your handling code here:
        this.jScrollPane1.setSize(this.getWidth(), this.getHeight());
    }//GEN-LAST:event_formComponentResized
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private LPlayerUILib.JImagePanel plItemList;
    // End of variables declaration//GEN-END:variables

    @Override
    public void processAction(LDownLoadItem sender, String actionName, String args) {
        selectedDownLoadItem = sender;
        removeAllSelect();
        sender.selectEnter();
        showTaskProgress(sender.downloadUrl);
        processActions(sender, actionName, args);

        if (actionName != null && actionName.equals(ActionLists.startDownload)) {
            if (checkDownloaderMaxCount()) {
                try {
                    sender.setMovieInfo("搜索资源");
                    sender.downloaderObj.start();
                    System.out.println("download");
                    sender.setToolTipText(sender.movieShowName + ",搜索资源中...");
                } catch (Exception ex) {
                    Logger.getLogger(LDownLoadList.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {
                try {
                    sender.stopDownload();
                    sender.setMovieInfo("等待");
                    sender.downloaderObj.stop();
                    sender.downloaderObj.dispose();
                    System.out.println("stop");
                    sender.setToolTipText(sender.movieShowName + ",等待开始");
                    //javax.swing.JOptionPane.showMessageDialog(null, "只能同时下载3个任务！");
                    sender.waitDownload();
                } catch (Exception ex) {
                    Logger.getLogger(LDownLoadList.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } else if (actionName != null && actionName.equals(ActionLists.stopDownload)) {
            try {
                sender.setMovieInfo("已停止");
                sender.downloaderObj.stop();
                sender.downloaderObj.dispose();
                System.out.println("stop");
                sender.setToolTipText(sender.movieShowName + ",已停止");
            } catch (Exception ex) {
                Logger.getLogger(LDownLoadList.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (actionName != null && actionName.equals(ActionLists.playMovie)) {
            if (lastPlayItem != null) {
                System.out.println("改变了状态" + lastPlayItem.downloadUrl);
                lastPlayItem.setPlayButton(true);
                lastPlayItem.setPauseButton(false);
            }
        }

        showTaskProgress(sender.downloadUrl);

        checkTaskFinish();

        checkItemButtonStates(sender);

    }
    private Date nowtime = new Date();

    private void reportDownLoadProgress(String did, double current, double total) {
        if (this.downloadProgresses.containsKey(did)) {
            SpeedEntry se = (SpeedEntry) this.downloadProgresses.get(did);
            se.length = total;
            if (se.startTime == 0 && current > se.current) {
                se.startTime = QvodPlayerUI.runTimes;
            }
            long ntime = QvodPlayerUI.runTimes - se.startTime;
            se.speed = (int) ((current - se.current) / ntime);
        } else {
            SpeedEntry see = new SpeedEntry(current, total);
            see.speed = 0;
            see.startTime = 0;
            this.downloadProgresses.put(did, see);
        }
    }

    public void stopAllDownload() {
        for (Object obj : PlayListLoader.playLists) {
            try {
                HistoryItem hin = (HistoryItem) obj;
                String str = hin.downloadUrl;
                this.downloadItemMap.get(str).downloaderObj.stop();
                this.downloadItemMap.get(str).downloaderObj.dispose();
                this.downloadItemMap.get(str).setMovieInfo("已停止");
            } catch (Exception ex) {
                Logger.getLogger(QvodDownLoad.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     *
     * @param qvodurl
     */
    private void showTaskProgress(String qvodurl) {
        LDownLoadItem dl = this.downloadItemMap.get(qvodurl);
        if (dl != null) {
            try {
                int totalsize = (int) dl.downloaderObj.movieFileLength;
                int currentsize = (int) dl.downloaderObj.getCurrentLength();
                String state = dl.downloaderObj.isRunning() ? "运行中" : "空闲中";
                String current = String.valueOf(currentsize / 1024);
                String maxium = String.valueOf(totalsize / 1024);
                //System.out.println(currentsize + "/"  + totalsize);
                int percent = (int) (((double) currentsize / (double) totalsize) * 100);
                long speedvalue = 0;
                long runsecond = 0;
                if (this.downloadProgresses.containsKey(qvodurl)) {
                    speedvalue = ((SpeedEntry) this.downloadProgresses.get(qvodurl)).speed;
                    runsecond = QvodPlayerUI.runTimes - ((SpeedEntry) this.downloadProgresses.get(qvodurl)).startTime;
                }
                if (speedvalue > 100000) {
                    speedvalue = 100;
                }
                dl.setDownloadProgress(percent);
                dl.setMovieInfo(percent + "%");
                dl.setToolTipText("<html>名称：" + dl.movieShowName + "<br>已下载" + current + "M<br>总共" + maxium + "M<br>完成度:" + percent + "%<br>速度：" + speedvalue + "K/S<br>当前状态：" + state + "," + dl.downloaderObj.qvodStateStr + "</html>");
//                if (this.selectedDownLoadItem != null && this.selectedDownLoadItem.downloadUrl.equals(qvodurl)) {
//                    this.processActions(dl, ActionLists.writeDownloadInfo, " 已下载" + current + "M 总共" + maxium + "M 完成度:" + percent + "% 速度：" + speedvalue + "K/S 当前状态：" + state + "," + dl.downloaderObj.qvodStateStr);
//                }
            } catch (Exception ex) {
                Logger.getLogger(QvodDownLoad.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void createFileLink(DownLoader sender) {
        try {
            File destpath = new File(ConfigLoader.config.downloadDir + "/" + this.downloadItemMap.get(sender.qvodUrl).movieShowName);

            if (destpath.exists()) {
                destpath.delete();
            }

            ArrayList al = new ArrayList();
            al.add("ln " + sender.qvodWorkDir + "/" + sender.getMovieFileName() + " " + destpath.getAbsolutePath());
            JAppToolKit.JDataHelper.writeAllLines(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyfinishmovie.sh", al);
            JAppToolKit.JRunHelper.runSysCmd("chmod +x " + JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyfinishmovie.sh");
            JAppToolKit.JRunHelper.runSysCmd(JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/copyfinishmovie.sh", false);
        } catch (Exception ex) {
            Logger.getLogger(LDownLoadList.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void onReportProgress(DownLoader sender, double currentlength, double totallength) {

        reportDownLoadProgress(sender.qvodUrl, currentlength, totallength);
        if (sender.qvodUrl != "") {
            //this.lblProgressInfo.setText((this.currentTaskIndex + 1) + "/" + PlayListLoader.playlist.playList.size());
            this.showTaskProgress(sender.qvodUrl);
        }

        try {
            if (((int) ((currentlength / totallength) * 100)) >= 98) {
                this.downloadItemMap.get(sender.qvodUrl).setPlayButton(true);
                createFileLink(sender);
                startNextTask();
            }
        } catch (Exception ex) {
            Logger.getLogger(LDownLoadList.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void onReportError(DownLoader sender, String code, String errormsg) {
        try {
            this.downloadItemMap.get(sender.qvodUrl).downloaderObj.stop();
            this.downloadItemMap.get(sender.qvodUrl).downloaderObj.dispose();
            this.downloadItemMap.get(sender.qvodUrl).setMovieInfo("超时退出");
            this.downloadItemMap.get(sender.qvodUrl).setToolTipText(this.downloadItemMap.get(sender.qvodUrl).movieShowName + ",超时退出");
        } catch (Exception ex) {
            Logger.getLogger(LDownLoadList.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void onReportFinish(final DownLoader sender) {
        File destpath = new File(ConfigLoader.config.downloadDir + "/" + this.downloadItemMap.get(sender.qvodUrl).movieShowName);
        //this.lblProgressInfo.setText((this.currentTaskIndex + 1) + "/" + PlayListLoader.playlist.playList.size());
//        if (destpath.exists()) {
//            //不需要复制
//        } else {
        try {
            SwingUtilities.invokeLater(new Runnable() {

                public void run() {
                    downloadItemMap.get(sender.qvodUrl).setDownLoadButton(false);
                    downloadItemMap.get(sender.qvodUrl).hideDownLoadButton();

                    if (currentPlay != null && currentPlay.downloadUrl.equals(sender.qvodUrl)) {
                        //当前播放不处理
                    } else {
                        downloadItemMap.get(sender.qvodUrl).setPlayButton(true);
                        downloadItemMap.get(sender.qvodUrl).setPauseButton(false);
                    }
                }
            });

            createFileLink(sender);
//                startNextTask();
        } catch (Exception ex) {
            Logger.getLogger(QvodDownLoad.class.getName()).log(Level.SEVERE, null, ex);
        }
//        }
    }

    @Override
    public void onReportStatus(DownLoader sender) {
        this.showTaskProgress(sender.qvodUrl);
    }

    @Override
    public void run() {
    }

    /*
     * 自动添加地址
     */
    protected void addQvodUrls(String urlcontent) {
        // TODO add your handling code here:
        if (!this.downloadItemMap.containsKey(urlcontent)) {

            try {
                String movieName = VodUrlFilters.getMovieStr(urlcontent);
                movieName = VodUrlFilters.decodeMovieName(movieName);
                LDownLoadItem ldi = this.addDownloadItem(urlcontent, movieName, movieName, "已停止");
                PlayListLoader.addHistory(urlcontent, ldi.downloaderObj.qvodWorkDir, ldi.downloaderObj.getDownLoadMovieStr(urlcontent), movieName);
                PlayListLoader.savePlayListWithXML();
                SingleHTTPServer.resultText = "ok";
                this.uploadDownloadList();
            } catch (Exception ex) {
                Logger.getLogger(QvodDownLoad.class.getName()).log(Level.SEVERE, null, ex);
                SingleHTTPServer.resultText = "error";
            }

        } else {
            SingleHTTPServer.resultText = "have";
        }
    }

    @Override
    public void reportQvodUrl(Object sender, String url) {
        //this.textQvodUrl.setText(url);
        addQvodUrls(url);
    }

    /**
     * 开始下载一个任务
     */
    private void startNextTask() {
        if (getDownloaderMaxCount() < 3) {
            ArrayList<HistoryItem> list = PlayListLoader.getNeedDownloadList();
            if (list.size() > 0) {
                for (HistoryItem hii : list) {
                    if (!this.downloadItemMap.get(hii.downloadUrl).downloaderObj.isRunning()) {
                        this.downloadItemMap.get(hii.downloadUrl).clickStartDownloadButton();
                        break;
                    }
                }
            }
        }
    }

    private void checkItemButtonStates(LDownLoadItem sender) {
        if (this.getDownloaderMaxCount() <= 0) {

            Iterator it = this.downloadItemMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                String key = (String)entry.getKey();
                LDownLoadItem value = (LDownLoadItem)entry.getValue();
                value.stopDownload();
            }            
        }
    }
}
